#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#include <unistd.h>
#include <signal.h>
#include <setjmp.h>

/*
jmp_buf buf;

void sig_int(int signo) {
	longjmp(buf,1);
}

int main() {
	int ret = 0;
	if ((ret=setjmp(buf)) != 0) 
		printf("jmp back %d\n", ret);
	
	signal(SIGINT, sig_int);
	pause();
}
*/

void pr_mask(char* str) {
	sigset_t sigset;
	int errno_save;

	errno_save = errno;
	if (sigprocmask(0, NULL, &sigset) < 0) {
		printf("sigprocmask error: %s\n", strerror(errno));
		return;
	}

	printf("%s ", str);

	if (sigismember(&sigset, SIGINT)) printf("SIGINT ");
	if (sigismember(&sigset, SIGQUIT)) printf("SIGQUIT ");
	if (sigismember(&sigset, SIGUSR1)) printf("SIGUSR1 ");

	printf("\n");
	errno = errno_save;
}

sigjmp_buf jmpbuf;
volatile sig_atomic_t canjump;

void sig_usr1(int signo) {
	time_t starttime;

	if (canjump == 0)
		return;

	pr_mask("starting sig_usr1: ");
	alarm(3);
	starttime = time(NULL);

	for (; ;)
		if (time(NULL) > starttime+5)
			break;
	pr_mask("finishing sig_usr1: ");

	canjump = 0;
	siglongjmp(jmpbuf, 1);
}

void sig_alarm(int signo) {
	pr_mask("in sig_alram: ");
}

int main() {
	if (signal(SIGUSR1, sig_usr1) == SIG_ERR)	{
		printf("set signal 1 error\n");
		return -1;
	}
	printf("set sig_usr1\n");

	if (signal(SIGALRM, sig_alarm) == SIG_ERR)	{
		printf("set signal 2 error\n");
		return -1;
	}
	printf("set sig_usr2\n");

	pr_mask("starting main: ");

	if (sigsetjmp(jmpbuf, 1)) {
		pr_mask("ending main: ");
		return 0;
	}
	canjump = 1;
	pause();
}